package pers.bc.utils.pub;
import java.util.*;

/**
 * 不需要导入外部包，自行编写的json字符串转map工具类
 *
 * @version 1.0<br>
 * @qualiFild pers.bc.utils.pub.JsonUtil.java<br>
 * @author：licheng<br>
 * @date Created on 2018年4月4日<br>
 */
public class JsonUtil
{
    private static ThreadLocal< JsonUtil > jsonUtil = new ThreadLocal< JsonUtil >();

    public static JsonUtil getInstance( )
    {
        JsonUtil df = jsonUtil.get();
        if (null == df)
        {
            synchronized ( JsonUtil.class )
            {
                if (null == df)
                {
                    df = new JsonUtil();
                    jsonUtil.set(df);
                }
            }
        }
        return df;
    }

    /************************************************************* <br>
     *
     *说明: Obj 转 json <br>
     *
     * @Description   <br>
     * @Date Created on 2022/8/17  21:56  <br>
     * @param obj <br>
     * @return java.lang.String  <br>
     * @Author LIBENCHENG
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static String transObj2Josn(Object obj) throws Exception
    { return CollectionUtil.transObj2Josn(obj); }

    /************************************************************* <br>
     *
     *说明: 压缩 json<br>
     *
     * @Description   <br>
     * @Date Created on 2022/8/17  21:56  <br>
     * @param json <br>
     * @return java.lang.String  <br>
     * @Author LIBENCHENG
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public String compressJson(String json)
    {
        StringBuffer bStr = new StringBuffer();
        Arrays.stream(json.split(PubEnvUtil.COMMA))
              .forEach(str ->
                       {
                           str = str.replace(PubEnvUtil.SINGLE_QUOTE, PubEnvUtil.EMPTY)
                                    .replace(PubEnvUtil.CRLF, PubEnvUtil.EMPTY)
                                    .replace(PubEnvUtil.QUOTE, PubEnvUtil.EMPTY)
                                    .replace(PubEnvUtil.TAB, PubEnvUtil.EMPTY)
                                    // .replace(PubEnvUtil.SPACE, PubEnvUtil.EMPTY)
                                    .replace(PubEnvUtil._N, PubEnvUtil.EMPTY).trim();
                           // if (str.contains(PubEnvUtil.LEFT_BRACE) || str.contains(PubEnvUtil.LEFT_SQ_BRACKET)
                           //         || str.contains(PubEnvUtil.RIGHT_BRACE) || str.contains(PubEnvUtil
                           //         .RIGHT_SQ_BRACKET))
                           // { str = str.replace(PubEnvUtil.SPACE, PubEnvUtil.EMPTY); }

                           bStr.append(str).append(PubEnvUtil.COMMA);
                       });

        return attackColon(StringUtil.toString(bStr.delete(bStr.length() - 1, bStr.length())));
    }

    private static String attackColon(String json)
    {
        char[] jsonChar = new char[json.length()];
        Character previous = '0';
        for (int index = 0; index < json.length(); index++)
        {
            char c = json.charAt(index);
            if ((PubEnvUtil.equals(previous, PubEnvUtil.LEFT_BRACE)
                    || PubEnvUtil.equals(previous, PubEnvUtil.COMMA))
                    && PubEnvUtil.equals(c, PubEnvUtil.EQUALS)) { jsonChar[index] = ':'; }
            else { jsonChar[index] = c; }
            if (PubEnvUtil.equals(c, PubEnvUtil.LEFT_BRACE)
                    || PubEnvUtil.equals(c, PubEnvUtil.COMMA)
                    || PubEnvUtil.equals(c, PubEnvUtil.EQUALS)) { previous = c; }
        }

        return String.valueOf(jsonChar);
    }


    /************************************************************* <br>
     *
     *说明: json 转 map<br>
     *
     * @Description   <br>
     * @Date Created on 2022/8/17  21:57  <br>
     * @param json <br>
     * @return java.lang.String  <br>
     * @Author LIBENCHENG
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static String json2MapStr(String json)
    {
        return json.replace(PubEnvUtil.LEFT_BRACKET, PubEnvUtil.LEFT_SQ_BRACKET)
                   .replace(PubEnvUtil.RIGHT_BRACKET, PubEnvUtil.RIGHT_SQ_BRACKET)
                   .replace(PubEnvUtil.COLON, PubEnvUtil.EQUALS)
                   .replace(PubEnvUtil.SINGLE_QUOTE, PubEnvUtil.EMPTY);
    }

    /**
     * *********************************************************** <br>
     * 说明： 必须首尾是[] <br>
     *
     * @param ori
     * @return <br>
     * @List<Object> <br>
     * @methods pers.bc.utils.pub.JsonUtilbc#toList <br>
     * @author licheng <br>
     * @date Created on 2020年4月5日 <br>
     * @time 下午8:00:38 <br>
     * @version 1.0 <br>
     * ************************************************************          <br>
     * @see <br>
     */
    public static List< Map< String,Object > > toList(String ori)
    { return getInstance().toListHelp(ori); }

    public static Map< String,Object > toMap(String ori)
    {
        // ori = removeBlack(ori);
        return getInstance().toMapHelp(ori);
    }

    public List< Map< String,Object > > toListHelp(String ori)
    {
        JudgeAssertUtil.checkAssert(PubEnvUtil.isEmpty(ori), "参数不能为空！");
        List< Map< String,Object > > list = new LinkedList< Map< String,Object > >();
        ori = compressJson(ori);
        String[] manyMaps = splitToSingeMap(ori);
        for (String e : manyMaps)
        { list.add(toResult(e)); }

        return list;
    }

    public Map< String,Object > toMapHelp(String ori)
    {
        JudgeAssertUtil.checkAssert(PubEnvUtil.isEmpty(ori), "参数不能为空！");
        ori = compressJson(ori);
        return toResult(ori);
    }

    /**
     * *********************************************************** <br>
     * 说明： 必须首尾是{} <br>
     *
     * @param ori
     * @return <br>
     * @Map<String,Object> <br>
     * @methods pers.bc.utils.pub.JsonUtilbc#toMapHelp <br>
     * @author licheng <br>
     * @date Created on 2020年4月5日 <br>
     * @time 下午8:01:19 <br>
     * @version 1.0 <br>
     * ************************************************************          <br>
     * @see <br>
     */
    private Map< String,Object > toResult(String ori)
    {
        if (ori.split(PubEnvUtil.COLON).length < 2)
        // { throw new RuntimeException(ori + "-->不是有效的JSON!"); }
        { throw new RuntimeException(ori + "-->不是有效的JSON!"); }

        Map< String,Object > map = new LinkedHashMap< String,Object >();
        String[] manyMaps = splitToSingeMap(ori);
        for (String e : manyMaps)
        {
            int indexOfF = 0;
            int shuangyh = 0;
            for (indexOfF = 0; indexOfF < e.length(); indexOfF++)
            {
                if (e.charAt(indexOfF) == '\"' && shuangyh == 0)
                {
                    shuangyh++;
                    continue;
                }
                if (e.charAt(indexOfF) == '\"' && shuangyh == 1)
                {
                    shuangyh--;
                    continue;
                }
                if (shuangyh == 0 && e.charAt(indexOfF) == ':')
                { break; }
            }
            if (indexOfF < e.length() - 1)
            {
                String fieldName = e.substring(0, indexOfF);
                String value = e.substring(indexOfF + 1, e.length());
                if (fieldName.charAt(0) == '\"')
                {// 字符串需要截取
                    fieldName = fieldName.substring(1, fieldName.length() - 1);
                }
                fieldName = fieldName.trim();
                if (value.charAt(0) == '{')
                {   // 子map元素
                    if (value.split(PubEnvUtil.COLON).length < 2)
                    { map.put(fieldName, value); }
                    else { map.put(fieldName, toResult(value)); }
                }
                else if (value.charAt(0) == '[')
                {// 子list元素
                    map.put(fieldName, toListHelp(value));
                }
                else if (value.charAt(0) == '\"')
                {// 字符串元素
                    map.put(fieldName, value.substring(1, value.length() - 1).trim());
                }
                else
                {// 其他元素
                    map.put(fieldName, value.trim());
                }

            }
        }
        return map;
    }


    /**
     * *********************************************************** <br>
     * 说明： 必须首尾是{}或者[]<br>
     *
     * @param ori
     * @return <br>
     * @String[] <br>
     * @methods pers.bc.utils.pub.JsonUtilbc#splitToSingeMap <br>
     * @author licheng <br>
     * @date Created on 2020年4月5日 <br>
     * @time 下午8:00:30 <br>
     * @version 1.0 <br>
     * ************************************************************          <br>
     * @see <br>
     */
    private String[] splitToSingeMap(String ori)
    {
        if (ori == null) { return null; }
        Map< Integer,Character > indexMap = getCommaIndex(ori);

        int lastIndex = 1;// 从第二个，第一个是{
        int lastLeftC = 0;// 左边的{数量，起始是0
        int lastLeftR = 0;// 左边的[数量，起始是0
        int splotLength = 0;// map个数
        int shuangyhao = 0;// 考虑{}有可能在""里面
        List< String > maps = new ArrayList();

        lastIndex = 1;// 从第二个，第一个是{
        lastLeftC = 0;// 左边的{数量，起始是0
        int mapIndex = 0;
        for (int index = 0; index < ori.length(); index++)
        {
            char c = ori.charAt(index);
            if (c == '\"' && shuangyhao == 0)
            {
                shuangyhao++;
                continue;
            }
            if (c == '\"' && shuangyhao == 1)
            {
                shuangyhao--;
                continue;
            }
            if (shuangyhao == 1)
            { continue; }
            if (c == '{')
            {
                lastLeftC++;
                continue;
            }
            if (c == '[')
            {
                lastLeftR++;
                continue;
            }
            if (lastLeftR + lastLeftC == 1
                    && ((c == ',' && PubEnvUtil.isNotEmptyObj(indexMap.get(index)))
                    || index >= ori.length() - 1))
            {
                maps.add(ori.substring(lastIndex, index).trim());
                lastIndex = index + 1;
                mapIndex++;
            }
            if (c == ']')
            { lastLeftR--; }
            if (c == '}')
            { lastLeftC--; }
        }

        return maps.toArray(new String[0]);
    }

    private Map< Integer,Character > getCommaIndex(String ori)
    {
        Map< Integer,Character > indexMap = new HashMap< Integer,Character >();
        char tempC = 'a';

        StringBuffer sb = new StringBuffer();
        List< Integer > sbint = new ArrayList();
        for (int index = 0; index < ori.length(); index++)
        {
            char c = ori.charAt(index);
            if (PubEnvUtil.equals(c, PubEnvUtil.COLON) || PubEnvUtil.equals(c, PubEnvUtil.COMMA))
            {
                sb.append(c);
                sbint.add(index);
            }
        }
        String oriNew = StringUtil.reverse(sb);
        sbint = (List< Integer >) CollectionUtil.reverse(sbint);
        for (int index = 0; index < oriNew.length(); index++)
        {
            char c = oriNew.charAt(index);
            if (PubEnvUtil.equals(c, PubEnvUtil.COMMA) && PubEnvUtil.equals(tempC, PubEnvUtil.COLON))
            { indexMap.put(sbint.get(index), c); }
            tempC = c;
        }

        return indexMap;
    }

    /**
     * *********************************************************** <br>
     * 说明： <br>
     *
     * @param ori
     * @return <br>
     * @String <br>
     * @methods pers.bc.utils.pub.JsonUtilbc#removeBlack <br>
     * @author licheng <br>
     * @date Created on 2020年4月5日 <br>
     * @time 下午8:01:09 <br>
     * @version 1.0 <br>
     * ************************************************************          <br>
     * @see <br>
     */
    private String removeBlack(String ori)
    {
        if (ori == null) { return null; }
        int shuangyhao = 0;// 考虑{}有可能在""里面
        boolean isblanck[] = new boolean[ori.length()];
        for (int index = 0; index < ori.length(); index++)
        {
            if (ori.charAt(index) == '\"' && shuangyhao == 0)
            {
                shuangyhao++;
                continue;
            }
            if (ori.charAt(index) == '\"' && shuangyhao == 1)
            {
                shuangyhao--;
                continue;
            }
            if (shuangyhao == 1)
            { continue; }
            if (//ori.charAt(index) == ' ' ||
                    ori.charAt(index) == '\n' ||
                            ori.charAt(index) == '\t' ||
                            ori.charAt(index) == '\r')
            { isblanck[index] = true; }
        }
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < ori.length(); i++)
        { if (!isblanck[i]) { sb.append(ori.charAt(i)); } }
        return sb.toString();
    }

}
